package com.zhupanlin.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;

/**
 * 描述信息：自定义授权服务器配置
 *
 * @author zhupanlin
 * @version 1.0
 * @date 2024/12/23 17:46
 */
/*@Configuration
@EnableAuthorizationServer*/ // 指定当前应用为授权服务器
public class InMemoryAuthorizationSeverConfig extends AuthorizationServerConfigurerAdapter {

    private final PasswordEncoder passwordEncoder;
    private final UserDetailsService userDetailsService;
    private final AuthenticationManager authenticationManager;

//    @Autowired
    public InMemoryAuthorizationSeverConfig(PasswordEncoder passwordEncoder, UserDetailsService userDetailsService, AuthenticationManager authenticationManager) {
        this.passwordEncoder = passwordEncoder;
        this.userDetailsService = userDetailsService;
        this.authenticationManager = authenticationManager;
    }

    /**
     * 用来配置授权服务器可以为哪些客户端授权
     * clientId secret redirectURI 使用哪种授权模式 授权码 简易模式 密码模式 客户端模式
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory().withClient("client")
                .secret(passwordEncoder.encode("secret"))
                .redirectUris("http://www.baidu.com")
                .authorizedGrantTypes("authorization_code", "refresh_token", "implicit", "password", "client_credentials")  // 授权码模式 仅支持授权码模式
                .scopes("read:user"); // 令牌允许获取的资源权限
    }

    /**
     * 配置授权服务器使用哪个 userDetailService
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.userDetailsService(userDetailsService); // 注入 userDetailService
        endpoints.authenticationManager(authenticationManager); // 注入authenticationManager
    }

    public static void main(String[] args) {
        System.out.println("new BCryptPasswordEncoder().encode(\"secret\") = " + new BCryptPasswordEncoder().encode("secret"));
    }

    /**
     *     授权码模式:
     *     1.请求用户是否授权 /oath/authorize
     *     完整路径: http://localhost:8080/oauth/authorize?client_id=client&response_type=code&redirect_uri=http://www.baidu.com
     *     2.授权之后根据获取的授权码获取令牌 /oauth/token      client_id secret redirectUri code  授权类型: authorization_code
     *     完整路径: curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=authorization_code&code=Iwvctx&redirect_uri=http://www.baidu.com' "http://client:secret@localhost:8080/oauth/token"
     *     {"access_token":"06847055-9437-4723-a97a-3772debb4861","token_type":"bearer","expires_in":43199,"scope":"read:user"}
     *     3.支持令牌刷新 /oauth/token id refresh_token 授权类型: refresh_token
     *     完整路径: curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=refresh_token&refresh_token=fb1b0b2a-f36d-489c-81c1-d0bddfc79f1d&client_id=client' "http://client:secret@localhost:8080/oauth/token"
     *     {"access_token":"24619e8c-8806-4f12-9cb9-abef25348bac","token_type":"bearer","refresh_token":"fb1b0b2a-f36d-489c-81c1-d0bddfc79f1d","expires_in":43199,"scope":"read:user"}
     */
}
